package com.zijie.hosptal.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zijie.hosptal.exception.EmailException;
import com.zijie.hosptal.exception.MaxException;
import com.zijie.hosptal.exception.RepeatedDay;
import com.zijie.hosptal.mapper.DoctorSchedulesMapper;
import com.zijie.hosptal.mapper.PatientMapper;
import com.zijie.hosptal.mapper.ReserveMapper;
import com.zijie.hosptal.pojo.po.DoctorSchedules;
import com.zijie.hosptal.pojo.po.Patient;
import com.zijie.hosptal.pojo.po.Reserve;
import com.zijie.hosptal.service.DoctorSchedulesService;
import com.zijie.hosptal.service.ReserveService;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.Transient;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Service
public class ReserveServiceImpl implements ReserveService {

    private ReserveMapper reserveMapper;
    private DoctorSchedulesMapper doctorSchedulesMapper;
//    Spring框架提供的邮件发送接口
    private JavaMailSender mailSender;
    private PatientMapper patientMapper;

    @Autowired
    public void setPatientMapper(PatientMapper patientMapper) {
        this.patientMapper = patientMapper;
    }

    @Autowired
    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    @Autowired
    public void setDoctorSchedulesMapper(DoctorSchedulesMapper doctorSchedulesMapper) {
        this.doctorSchedulesMapper = doctorSchedulesMapper;
    }

    @Autowired
    public void setReserveServiceMapper(ReserveMapper reserveMapper) {
        this.reserveMapper = reserveMapper;
    }

    @Override
    public Page<Reserve> list(Page<Reserve> reservePage, Reserve reserve) {
        return reserveMapper.findList(reservePage,reserve);
    }

    @Transactional
    @Override
    public boolean save(Reserve reserve) {
        //寻找活动编号
        Integer scheduleId = reserve.getScheduleId();
        //找到活动
        DoctorSchedules doctorSchedules = doctorSchedulesMapper.getById(scheduleId);
        LocalDateTime startTime = doctorSchedules.getStartTime();
        List<Integer>  count=reserveMapper.selectToDay(startTime,reserve.getPatientId());
        for (Integer i : count) {
            DoctorSchedules doctorSchedulesMapperById = doctorSchedulesMapper.getById(i);
// 将 LocalDateTime 转换为 LocalDate 来比较
            boolean equals = doctorSchedulesMapperById.getStartTime().toLocalDate()
                    .equals(startTime.toLocalDate());
            if (equals){
                throw new RepeatedDay("你在当前日期有预约，把机会留给其他人吧");
            }
        }
        reserve.setDoctorId(doctorSchedules.getDoctorId());
        //为这个新的预约设置预约的时间
        reserve.setReserveTime(LocalDateTime.now());
        //查看当天是否有其他预约   一天只能预约一次  防止恶意预约
        Reserve reserve1 = reserveMapper.selectByReserveTime(reserve.getReserveTime(),reserve.getPatientId());
        if (reserve1!=null){
            throw new RepeatedDay("您今天已经预约过活动了，把机会留给其他人吧");
        }

        //判断这个活动是否已经参加
        Integer bool=reserveMapper.selectByPatientId(reserve.getPatientId(),reserve.getScheduleId());
        if (bool!=null){
            throw new RepeatedDay("您已经预约过这个活动了");
        }
        //判断这个时间是否在活动时间段内
        Boolean flag1=doctorSchedulesMapper.selectByReserTime(reserve);
        if (!flag1){
            return false;
        }
        //查询当前要添加的活动是否已经满员
        //最大人数
        maxCount(doctorSchedules,reserve);
        reserve.setStatus("1");
        return reserveMapper.insert(reserve) > 0;
    }

    @Transactional
    @Override
    public boolean updateById(Reserve reserve) {
        Integer scheduleId1 = reserve.getScheduleId();
        DoctorSchedules doctorSchedules1 = doctorSchedulesMapper.getById(scheduleId1);
        if (Objects.equals(doctorSchedules1.getStatus(), "2")){
            doctorSchedules1.setStatus("1");
            doctorSchedulesMapper.updateById(doctorSchedules1);
        }
        LocalDateTime startTime = doctorSchedules1.getStartTime();
        List<Integer>  count=reserveMapper.selectToDay(startTime,reserve.getPatientId());
        for (Integer i : count) {
            DoctorSchedules doctorSchedulesMapperById = doctorSchedulesMapper.getById(i);
// 将 LocalDateTime 转换为 LocalDate 来比较
            boolean equals = doctorSchedulesMapperById.getStartTime().toLocalDate()
                    .equals(startTime.toLocalDate());
            if (equals){
                throw new RepeatedDay("你在当前日期有预约，把机会留给其他人吧");
            }
        }
        //为这个新的预约设置预约的时间
        reserve.setReserveTime(LocalDateTime.now());

        //判断这个时间是否在活动时间段内
        Boolean flag=doctorSchedulesMapper.selectByReserTime(reserve);
        if (!flag){
            return false;
        }
        Integer bool=reserveMapper.selectByPatientId(reserve.getPatientId(),reserve.getScheduleId());
        if (bool!=null){
            throw new RepeatedDay("您已经预约过这个活动了");
        }
        Integer scheduleId = reserve.getScheduleId();
        DoctorSchedules doctorSchedules = doctorSchedulesMapper.getById(scheduleId);
        reserve.setDoctorId(doctorSchedules.getDoctorId());
        //查询当前要添加的活动是否已经满员
        maxCount(doctorSchedules,reserve);
        return reserveMapper.updateById(reserve) > 0;
    }

    @Override
    public boolean rateReserve(Reserve reserve) {
        reserve.setCommentTime(LocalDateTime.now());
        return reserveMapper.rateReserve(reserve);
    }

    @Transactional
    @Override
    public boolean saveOrUpdateBatch(List<Reserve> list) {
        for (Reserve reserve : list) {
            if (Objects.equals(reserve.getStatus(), "0")){
                Integer scheduleId = reserve.getScheduleId();
                DoctorSchedules doctorSchedules1 = doctorSchedulesMapper.getById(scheduleId);
                if (Objects.equals(doctorSchedules1.getStatus(), "2")){
                    doctorSchedules1.setStatus("1");
                }
                doctorSchedulesMapper.updateByReserve(doctorSchedules1);
            }
        }
        return reserveMapper.saveOrUpdateBatch(list);
    }

    @Transactional
    @Override
    public boolean removeReserve(Reserve reserve) {
        Integer scheduleId = reserve.getScheduleId();
        DoctorSchedules doctorSchedules = doctorSchedulesMapper.getById(scheduleId);
        if (Objects.equals(doctorSchedules.getStatus(), "2")){
            doctorSchedules.setStatus("1");
            doctorSchedulesMapper.updateById(doctorSchedules);
        }
        return reserveMapper.removeReserve(reserve);
    }

    @Override
    public Page<Reserve> listReserves(Page<Reserve> reservePage, Reserve reserve) {
        return reserveMapper.listReserves(reservePage,reserve);
    }


    @Override
    public boolean sendEmail(Integer patientId, String content) {
//        MimeMessage
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
        String myEmail = "3286975374@qq.com";
        String displayName="七七义诊活动通知";
        Patient patient = patientMapper.selectByIdToEmain(patientId);
        //目标地址
        String emailAddress = patient.getEmail();
        String subject="义诊通知";
        String text="尊敬的"+patient.getName()+"：\n"+content;
//        设置邮件主题和正文内容
        try {
            mimeMessageHelper.setFrom(myEmail,displayName);
            mimeMessageHelper.setTo(emailAddress);
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(text);
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            throw new EmailException("邮件发送异常请联系管理员");
        }
        return true;
    }


    //判断最大人数
    private void maxCount(DoctorSchedules doctorSchedules,Reserve reserve){
        //最大人数
        Integer totalSlots = doctorSchedules.getTotalSlots();
        //当前人数
        Integer nowCount=reserveMapper.getByReserveId(reserve.getScheduleId(),"0");
        if (nowCount+1==totalSlots){
            if (!Objects.equals(doctorSchedules.getStatus(), "2")){
                doctorSchedules.setStatus("2");
                doctorSchedulesMapper.updateByReserve(doctorSchedules);
            }
        }
        if (nowCount>=totalSlots){
            throw new MaxException("活动已达到最大人数无法继续报名");
        }
    }
}
